/**
 * 
 */
package com.urg.parser;

/**
 * @author UrG
 * 
 */
public class BracketAnalyzer {

	/**
	 * Gets the index of start bracket in given expression
	 * 
	 * @param expression
	 * @return
	 */
	public static int getStartBracketIndex(String expression) {
		int startBracketIndex = -1;
		if (verifyBrackets(expression)) {
			startBracketIndex = expression.indexOf("(");
		}
		return startBracketIndex;
	}

	/**
	 * Gets the end bracket index (logical) in given expression
	 * 
	 * @return
	 */
	public static int getEndBracketIndex(String expression) {
		int endBracketIndex = -1;
		if (verifyBrackets(expression)) {
			int startBracketIndex = getStartBracketIndex(expression);
			if (startBracketIndex > -1) {
				int leftBracketCount = 0;
				int rightBracketCount = 0;
				for (int i = startBracketIndex; i < expression.length(); i++) {
					if (String.valueOf(expression.charAt(i)).equals("(")) {
						leftBracketCount++;
					}
					if (String.valueOf(expression.charAt(i)).equals(")")) {
						rightBracketCount++;
					}
					if (leftBracketCount == rightBracketCount
							&& i != startBracketIndex) {
						endBracketIndex = i;
						break;
					}
				}
			}

		}
		return endBracketIndex;
	}

	/**
	 * Verifies if the given expression has proper number of start and
	 * endbrackets.
	 * 
	 * @param expression
	 *            expression
	 * @return validity
	 */
	public static boolean verifyBrackets(String expression) {
		boolean isValid = false;
		int countLeftBrackets = 0;
		int countRightBrackets = 0;
		for (int i = 0; i < expression.length(); i++) {
			if (String.valueOf(expression.charAt(i)).equalsIgnoreCase("(")) {
				countLeftBrackets++;
			}
			if (String.valueOf(expression.charAt(i)).equalsIgnoreCase(")")) {
				countRightBrackets++;
			}
		}
		if (countLeftBrackets == countRightBrackets) {
			isValid = true;
		}
		return isValid;
	}

	/**
	 * Trims the expression smartly.
	 * 
	 * @param expression
	 *            expression
	 * @return expression with end brackets trimed
	 */
	public static String smartlyTrimEndBrackets(String expression) {
		expression = expression.trim();
		boolean canTrim = verifyBrackets(expression);
		int startBracketIndex = 0;
		int endBracketIndex = expression.length() - 1;
		int countLeftBrackets = 0;
		int countRightBrackets = 0;
		// int indexEndBracket = -1;
		if (canTrim) {
			for (int i = 0; i < expression.length(); i++) {
				if (String.valueOf(expression.charAt(i)).equalsIgnoreCase("(")) {
					if (countLeftBrackets == countRightBrackets) {
						startBracketIndex = i;
					}
					countLeftBrackets++;
				}
				if (String.valueOf(expression.charAt(i)).equalsIgnoreCase(")")) {
					endBracketIndex = i;
					countRightBrackets++;
				}
				if (countLeftBrackets == countRightBrackets && i != 0
						&& i < expression.length() - 1 && countLeftBrackets > 0) {
					canTrim = false;
					break;
				}
				if (countLeftBrackets == countRightBrackets
						&& endBracketIndex > startBracketIndex) {
					if (startBracketIndex != 0
							&& endBracketIndex == expression.length() - 1) {
						canTrim = false;
						break;
					}
				}
			}
		}
		if (canTrim) {
			if (expression.startsWith("(") && expression.endsWith(")")) {
				expression = expression.substring(1, expression.length() - 1);
				expression = expression.trim();
				expression = smartlyTrimEndBrackets(expression);
			}
		}
		return expression;
	}

	/**
	 * Trims the end brackets without checking if more conditions exists.
	 * 
	 * @param expression
	 *            expression
	 * @return expression with end brackets trimmed
	 */
	public static String simplyTrimEndBrackets(String expression) {
		expression = expression.trim();
		while (verifyBrackets(expression) && expression.startsWith("(")
				&& expression.endsWith(")")) {
			expression = expression.substring(1, expression.length() - 1);
			expression = expression.trim();
		}
		return expression;
	}

	/**
	 * Adds start and end bracket to given expression.
	 * 
	 * @param expression
	 *            expression
	 * @return expression with end brackets
	 */
	public static String addEndBrackets(String expression) {
		return "(" + expression + ")";
	}
}
